package com.immediatus.engine.contracts;

import com.immediatus.contracts.IUpdateHandler;
import com.immediatus.engine.util.ParameterCallable;
import com.immediatus.engine.util.Transformation;
import com.immediatus.graphics.contracts.IDrawable;

import java.util.Comparator;


public interface IUnit extends IDrawable, IUpdateHandler{
    public boolean isVisible();
    public void setVisible(final boolean visible_);

    public boolean isIgnoreUpdate();
    public void setIgnoreUpdate(boolean ignoreUpdate_);

    public boolean isChildrenVisible();
    public void setChildrenVisible(final boolean childrenVisible_);

    public boolean isChildrenIgnoreUpdate();
    public void setChildrenIgnoreUpdate(boolean childrenIgnoreUpdate_);

    public int getZIndex();
    public void setZIndex(final int zIndex_);

    public float getX();
    public float getY();
    public float getInitialX();
    public float getInitialY();
    public void setInitialPosition();
    public void setPosition(final IUnit unit_);
    public void setPosition(final float x_, final float y_);

    public boolean isRotated();
    public float getRotation();
    public void setRotation(final float rotation_);
    public float getRotationCenterX();
    public float getRotationCenterY();
    public void setRotationCenterX(final float x_);
    public void setRotationCenterY(final float y_);
    public void setRotationCenter(final float x_, final float y_);

    public boolean isScaled();
    public float getScaleX();
    public float getScaleY();
    public void setScaleX(final float sx_);
    public void setScaleY(final float sy_);
    public void setScale(final float s_);
    public void setScale(final float sx_, final float sy_);
    public float getScaleCenterX();
    public float getScaleCenterY();
    public void setScaleCenterX(final float x_);
    public void setScaleCenterY(final float y_);
    public void setScaleCenter(final float x_, final float y_);

    public float getRed();
    public float getGreen();
    public float getBlue();
    public float getAlpha();
    public void setAlpha(final float a_);
    public void setColor(final float r_, final float g_, final float b_);
    public void setColor(final float r_, final float g_, final float b_, final float a_);

    public float[] getLayerCenterCoordinates();
    public float[] convertLocalToLayerCoordinates(final float x_, final float y_);
    public float[] convertLocalToLayerCoordinates(final float x_, final float y_, final float[] reuse_);
    public float[] convertLocalToLayerCoordinates(final float[] coord_);
    public float[] convertLocalToLayerCoordinates(final float[] coord_, final float[] reuse_);
    public float[] convertLayerToLocalCoordinates(final float x_, final float y_);
    public float[] convertLayerToLocalCoordinates(final float x_, final float y_, final float[] reuse_);
    public float[] convertLayerToLocalCoordinates(final float[] coord_);
    public float[] convertLayerToLocalCoordinates(final float[] coord_, final float[] reuse_);

    public Transformation getLocalToLayerTransformation();
    public Transformation getLayerToLocalTransformation();

    public boolean hasParent();
    public IUnit getParent();
    public void setParent(final IUnit unit_);
    public int getChildCount();
    public void onAttached();
    public void onDetached();
    public void attachChild(final IUnit unit_);
    public boolean attachChild(final IUnit unit_, final int index_);
    public IUnit getChild(final int index_);
    public IUnit getFirstChild();
    public IUnit getLastChild();
    public int getChildIndex(final IUnit unit_);
    public boolean setChildIndex(final IUnit unit_, final int index_);
    public IUnit findChild(final IEntityMatcher entityMatcher_);
    public boolean swapChildren(final int indexA_, final int indexB_);
    public boolean swapChildren(final IUnit unitA_, final IUnit unitB_);
    public void sortChildren();
    public void sortChildren(final Comparator<IUnit> entityComparator_);
    public boolean detachSelf();
    public boolean detachChild(final IUnit unit_);
    public IUnit detachChild(final IEntityMatcher entityMatcher_);
    public boolean detachChildren(final IEntityMatcher entityMatcher_);
    public void detachChildren();

    public void callOnChildren(final IEntityCallable entityCallable_);
    public void callOnChildren(final IEntityMatcher entityMatcher_, final IEntityCallable entityCallable_);

    public void registerUpdateHandler(final IUpdateHandler updateHandler_);
    public boolean unregisterUpdateHandler(final IUpdateHandler updateHandler_);
    public boolean unregisterUpdateHandlers(final IUpdateHandlerMatcher updateHandlerMatcher_);
    public void clearUpdateHandlers();

    public void registerEntityModifier(final IUnitModifier modifier_);
    public boolean unregisterEntityModifier(final IUnitModifier modifier_);
    public boolean unregisterEntityModifiers(final IUnitModifier.IEntityModifierMatcher entityModifierMatcher_);
    public void clearEntityModifiers();

    public void setUserData(Object userData_);
    public Object getUserData();

    public interface IEntityMatcher extends IMatcher<IUnit>{
        @Override
        public boolean matches(final IUnit unit_);
    }
    public interface IEntityCallable extends ParameterCallable<IUnit>{
        @Override
        public void call(final IUnit unit_);
    }
}
